# import sys
# sys.path.append('..')
import json
import os
import datetime
import asyncio
import shutil
import tornado.web
import tornado.websocket
from tornado.web import RequestHandler
# from pycket.session import SessionMixin
from tornado import httputil
from tornado import iostream
from views.forms import DownloadForm
from views.download import Download
from views.fastdownload import new_download
from config import appconfig
from utils import ProStatus
from logger import logger


class BaseHandler(RequestHandler):
	@property
	def db(self):
		return self.application.db

	@property
	def download(self)->Download:
		return self.application.download


class IndexHandler(BaseHandler):
	def get(self,*args,**kwargs):
		form = DownloadForm()
		self.render('index.html',form=form)

class PlayerHandler(BaseHandler):
	def get(self,*args,**kwargs):
		self.render('flv.html')


class DownloadHandler(BaseHandler):
	"""新增下载"""
	def post(self,*args,**kwargs):
		form = DownloadForm()
		name = self.get_body_argument('filename','')
		url = self.get_body_argument('fileurl','')
		data = self.get_body_argument('filepath','')
		savepath = self.get_body_argument('savepath','')
		if url!='':
			self.download.getUrl(url,name,savepath,data)
		resp = json.dumps({"code":0,"msg":"success"})
		self.set_header("Content-Type","application/json")
		self.write(resp)

class DownloadingListHandler(BaseHandler):
	"""下载中列表"""
	def get(self,*args,**kwargs):
		res = self.download.getStatus()
		resp = json.dumps({"code":0,"list":res})
		self.set_header("Content-Type","application/json")
		self.write(resp)

class ReDownloadHandler(BaseHandler):
	"""重新下载"""
	def get(self,*args,**kwargs):
		id = self.get_query_argument('id',None)
		status = int(self.get_query_argument('status'))
		status = self.download.redownload(id)
		resp = json.dumps({"code":0,"status":status})
		self.set_header("Content-Type","application/json")
		self.write(resp)

class CutVideoHandler(BaseHandler):
	"""片段截取"""
	def get(self,*args,**kwargs):
		section = self.get_query_argument('section')
		cuttime = self.timeStrToInt(self.get_query_argument('cuttime',''))
		needtime = self.download.getCutTime(section,cuttime)
		resp = json.dumps({"code":0,"msg":"success","data":needtime})
		self.set_header("Content-Type","application/json")
		self.write(resp)

	def post(self,*args,**kwargs):
		section = self.get_body_argument('section','')
		start_time1 = self.timeStrToInt(self.get_body_argument('start-time1',''))
		end_time1 = self.timeStrToInt(self.get_body_argument('end-time1',''))
		start_time2 = self.timeStrToInt(self.get_body_argument('start-time2',''))
		end_time2 = self.timeStrToInt(self.get_body_argument('end-time2',''))
		start_time3 = self.timeStrToInt(self.get_body_argument('start-time3',''))
		end_time3 = self.timeStrToInt(self.get_body_argument('end-time3',''))
		start_time4 = self.timeStrToInt(self.get_body_argument('start-time4',''))
		end_time4 = self.timeStrToInt(self.get_body_argument('end-time4',''))
		start_time5 = self.timeStrToInt(self.get_body_argument('start-time5',''))
		end_time5 = self.timeStrToInt(self.get_body_argument('end-time5',''))
		start_time6 = self.timeStrToInt(self.get_body_argument('start-time6',''))
		end_time6 = self.timeStrToInt(self.get_body_argument('end-time6',''))

		timelist = []
		if start_time1 != None and end_time1 != None:
			if end_time1>start_time1:
				timelist.append((start_time1,end_time1))
		if start_time2 != None and end_time2 != None:
			if end_time2>start_time2:
				timelist.append((start_time2,end_time2))
		if start_time3 != None and end_time3 != None:
			if end_time3>start_time3:
				timelist.append((start_time3,end_time3))
		if start_time4 != None and end_time4 != None:
			if end_time4>start_time4:
				timelist.append((start_time4,end_time4))
		if start_time5 != None and end_time5 != None:
			if end_time5>start_time5:
				timelist.append((start_time5,end_time5))
		if start_time6 != None and end_time6 != None:
			if end_time6>start_time6:
				timelist.append((start_time6,end_time6))
		# logger.info(timelist)
		data = self.download.cutvideo(section,timelist)
		resp = json.dumps({"code":0,"msg":"success","data":data})
		self.set_header("Content-Type","application/json")
		self.write(resp)

	def timeStrToInt(self,timestr):
		timeInt = None
		if timestr:
			h,m,s = timestr.split(':')
			timeInt = int(h)*3600+int(m)*60+int(s)
		return timeInt

class StopHandler(BaseHandler):
	"""开始/暂停"""
	def get(self,*args,**kwargs):
		id = self.get_query_argument('id',None)
		status = int(self.get_query_argument('status'))
		status = self.download.stopTask(id)
		resp = json.dumps({"code":0,"status":status})
		self.set_header("Content-Type","application/json")
		self.write(resp)

class DelHandler(BaseHandler):
	"""删除下载"""
	def get(self,*args,**kwargs):
		id = self.get_query_argument('id')
		dtype = int(self.get_query_argument('type'))
		msg = self.download.deleteTask(id,dtype)
		ProStatus().triggerDeleteData(id)
		resp = json.dumps({"code":0,"msg":msg})
		self.set_header("Content-Type","application/json")
		self.write(resp)

class DeleteMovieHandler(BaseHandler):
	"""删除电影"""
	async def get(self,*args,**kwargs):
		id = self.get_query_argument('id')
		resp = json.dumps({"code":0,"msg":"删除成功"})
		msg = []
		movie = self.db.get('select * from movie where id=%s'%id)
		if movie:
			rlt = self.download.deletemovie(id,movie)
			# rlt = self.deletemovie(id,movie)
			if rlt:
				msg.append(rlt)
		if msg:
			msg = ' '.join(msg)
			resp = json.dumps({"code":0,"msg":"删除失败：%s"%msg})
		self.set_header("Content-Type","application/json")
		self.write(resp)



class DeleteCutHandler(BaseHandler):
	"""刪除片段"""
	def get(self,*args,**kwargs):
		id = self.get_query_argument('id')
		try:
			url = self.get_query_argument('url')
			url = os.path.split(url)[1]
			play_list = self.db.query('select indexname from movie where id="{id}"'.format(id=id))
			play_list = play_list[0]['indexname']
			play_list = play_list.split(' ')
			for i in range(len(play_list)):
				if url==play_list[i]:
					play_list.pop(i)
					break
			play_list = ' '.join(play_list)
		except:
			pass
		sqlstr = 'update movie set indexname="{indexname}" where id="{id}"'.format(indexname=play_list,id=id)
		self.db.execute(sqlstr)
		resp = json.dumps({"code":0,"msg":play_list})
		self.set_header("Content-Type","application/json")
		self.write(resp)

class AddMovieHandler(BaseHandler):
	"""手动添加"""
	def get(self,*args,**kwargs):
		newmovies = self.download.getNewMovie()
		# resp = json.dumps({"code":0,"msg":"","page_data":newmovies,"movie_count":len(newmovies)})
		self.render('add.html', page_data=newmovies,movie_count = len(newmovies))
	def post(self,*args,**kwargs):
		name = self.get_body_argument('name',None)
		author = self.get_body_argument('author','')
		ftype = self.get_body_argument('ftype',None)
		if name and ftype:
			status,msg = self.download.addNewMovie(name,author,ftype)
			if status:
				resp = json.dumps({"code":0,"msg":msg})
			else:
				resp = json.dumps({"code":101,"msg":msg})
		else:
			resp = json.dumps({"code":101,"msg":"name或者ftype为空"})
		self.set_header("Content-Type","application/json")
		self.write(resp)

class ConvertMovieHandler(BaseHandler):
	"""合并cut文件"""
	def get(self,*args,**kwargs):
		cutmovie = self.db.query("select * from movie where cuttype>1")
		# resp = json.dumps({"code":0,"msg":"","page_data":newmovies,"movie_count":len(newmovies)})
		self.render('convert.html', page_data=cutmovie,movie_count = len(cutmovie))
	def post(self,*args,**kwargs):
		movies = self.get_body_arguments('movies[]',None)
		if movies:
			# movies=['1634568697294', '1634573335766']
			if len(movies)>1:
				msg = self.download.convert_movie(movies)
				if len(msg)>0:
					resp = json.dumps({"code":1220,"msg":msg})
				else:
					resp = json.dumps({"code":0,"msg":"合并"+str(movies)+"成功"})
		else:
			resp = json.dumps({"code":101,"msg":"未勾选"})
		self.set_header("Content-Type","application/json")
		self.write(resp)

class AppendHandler(BaseHandler):
	"""导入"""
	def get(self,*args,**kwargs):
		section = self.get_query_argument('id','')
		self.download.appendMovie(section)
		data = {'code':0,'section':section,'msg':'添加cg'}
		resp = json.dumps(data)
		self.set_header("Content-Type","application/json")
		self.write(resp)

class SwitchHandler(BaseHandler):
	"""切换类型"""
	def get(self,*args,**kwargs):
		section = self.get_query_argument('id','')
		area = self.db.get('select area from movie where id=%s'%section)['area']
		if area==2:
			area=0
		else:
			area=2
		self.db.execute('update movie set area={area} where id="{id}"'.format(area=area,id=section))
		data = {'code':0,'section':section,'area':area,'msg':'修改cg'}
		resp = json.dumps(data)
		self.set_header("Content-Type","application/json")
		self.write(resp)

class AreaHandler(BaseHandler):
	"""切换area"""
	def get(self,*args,**kwargs):
		section = self.get_query_argument('id','')
		area = int(self.get_query_argument('area',0))
		self.db.execute('update movie set area={area} where id="{id}"'.format(area=int(area),id=section))
		data = {'code':0,'section':section,'area':str(area),'msg':'修改cg'}
		resp = json.dumps(data)
		self.set_header("Content-Type","application/json")
		self.write(resp)


class Static_FileHandler(tornado.web.StaticFileHandler):

	async def prepare(self,*args,**kwargs):
		index = self.path_kwargs.get('index',None)
		section = self.path_kwargs.get('section',None)
		if index!=None:
			await self.application.download.checkindex(section, index)
		self.root = self.application.download.checkrootdir(section)
		pass

	async def get(self,section=None,index=None,filepath=None,*args,**kwargs):
		await super().get(path=filepath,*args,**kwargs)


# cuttype=1/2/3 	未cut过/已cut过/合并后的
# area=0/1/2		未设置/cn/jp
class HomeHandler(BaseHandler):
	def get(self,*args,**kwargs):
		movies = self.db.query('select * from movie where area=0 ORDER BY addtime')
		self.render('home.html',page_data=movies)

class Home2Handler(BaseHandler):
	def get(self,*args,**kwargs):
		self.render('videos.html')

class GetVideosHandler(BaseHandler):
	"""获取电影列表"""
	def get(self):
		area = int(self.get_query_argument('area',0))
		author = self.get_query_argument('author', '')	# 如果传了author，优先使用
		kwards = self.get_query_argument('kwards','')
		if kwards:	# 搜索时
			movies = self.db.query('select * from movie where area={} and name like "%{}%" ORDER BY addtime'.format(area,kwards))
		elif author!='':	# 按名字搜索时
			if author=='无':
				author = ''
				movies = self.db.query('select * from movie where author="" ORDER BY addtime')
			else:
				movies = self.db.query('select * from movie where author like "%{}%" ORDER BY addtime'.format(author))
		else:
			movies = self.db.query('select * from movie where area={} ORDER BY addtime'.format(area))
		resp = {'code':0,'data':{'list':movies,'area':area},'msg':'请求成功'}
		resp = json.dumps(resp)
		self.write(resp)
		self.finish()

class AuthorHandler(BaseHandler):
	"""获取author"""
	def get(self):
		name = self.get_query_argument('name','')
		authorlist = []
		if name=='':
			curr_name = None
			nums = 0
			authors = self.db.query('select author,count(author) as num from movie GROUP BY author ORDER BY author desc,addtime'.format(name))
			authorlist = sorted(authors,key=lambda x:x['num'],reverse=True)
		else:
			movies = self.db.query('select * from movie where author like "%{}%" ORDER BY addtime'.format(name))
			authorlist.append({'author':name,'num':len(movies)})
		resp = {'code':0,'data':{'list':authorlist},'msg':''}
		resp = json.dumps(resp)
		self.write(resp)
		self.finish()
class Home3Handler(BaseHandler):
	def get(self,*args,**kwargs):
		movies = self.db.query('select * from movie where cuttype=2 ORDER BY addtime')
		self.render('home.html',page_data=movies)


class SearchHandler(BaseHandler):
	def get(self,*args,**kwargs):
		area = self.get_query_argument('area', 0)
		kwards = self.get_query_argument('kwards', '')
		self.redirect('/getvideos?area='+area+'&kwards='+kwards)

class PlayHandler(BaseHandler):
	"""播放"""
	def get(self,section=None,*args,**kwargs):
		self.render("play.html")

class PlayVideoHandler(BaseHandler):
	"""播放数据"""
	def get(self,*args,**kwargs):
		section = self.get_query_argument('section','')
		if section:
			movie = self.download.getplayurl(section,tag=1)
			ulist = []
			for i in range(len(movie['urls'])):
				ulist.append([movie['urls'][i],'%02d'%(i+1)])
			movie['urls'] = ulist
		else:
			url = self.get_query_argument('url','')
			id = self.get_query_argument('id','')
			if url!='':
				movie = self.download.getMovieForm()
				movie['name'] = url
				movie['url'] = url
				movie['urls'] = [[movie['url'], '01']]
			elif id!='':
				movie = self.download.getplayurl(id,tag=0)
				ulist = []
				for i in range(len(movie['urls'])):
					ulist.append([movie['urls'][i], '%02d'%(i+1)])
				movie['urls'] = ulist
		resp = {'code':0,'data':movie,'msg':''}
		resp = json.dumps(resp)
		self.write(resp)
		self.finish()
class UploaderFileHandler(BaseHandler):
	"""上传文件"""
	def initialize(self,path,*args,**kwargs):
		self.image_path = path

	async def post(self,*args,**kwargs):
		ret = {'code':200,'msg':'success'}
		section = self.get_query_argument('id',None)
		file_metas = self.request.files.get('image',None)
		if not file_metas:
			ret['code'] = 100
			ret['msg'] = 'Invalid args'
			resp = json.dumps(ret)
			self.set_header("Content-Type","application/json")
			self.write(resp)
			return
		for meta in file_metas:
			filename = meta['filename']
			_,ftype = os.path.splitext(filename)
			filename = section+ftype
			file_path = os.path.join(self.image_path,filename)
			with open(file_path,'wb') as up:
				up.write(meta['body'])
			self.db.execute('update movie set logo="{logo}" where id="{id}"'.format(logo=filename,id=section))
		resp = json.dumps(ret)
		self.set_header("Content-Type","application/json")
		self.write(resp)




class HeaderHandler(RequestHandler):
	def set_default_headers(self):
		self.set_header("Content-Type","application/json")

	def post(self,*args,**kwargs):
		pass

	def get(self,*args,**kwargs):
		pass

class StatusHandler(RequestHandler):
	def get(self,*args,**kwargs):
		self.set_status(404,reason="Dont find!")
		self.write("****")

class RedirectHandler(RequestHandler):
	def get(self,*args,**kwargs):
		self.redirect('/write')

class ErrorHandler(RequestHandler):
	def write_error(self,status_code,**kwargs):
		if status_code == 500:
			code = 500
			self.write('服务器内部错误')
		elif status_code == 400:
			code=400
			self.write('预先设置错误')
		self.set_status(code)

	def get(self,*args,**kwargs):
		flag = self.get_query_argument("flag")
		if flag==0:
			self.send_error(500)
			#注意在self.send_error(500)以下同级的内容不会继续执行
		self.write('right')


class BoyHandler(RequestHandler):
	def initialize(self,word3,word4):		#该方法会在http方法（这里为get方法）之前调用
		self.word3 = word3
		self.word4 = word4
	def get(self,*args,**kwargs):
		print(self.word3,self.word4)
		self.write("good boy")


'''Tornado 定义了 tornado.websocket.WebSocketHandler 类用于处理 WebSocket 链接的请求，
应用开发者应该继承该类并实现其中的open()、on_message()、on_close() 函数
'''
#基类
class BaseWebSocketHandler(tornado.websocket.WebSocketHandler):
	def get_current_user(self):
		# current_user = self.session.get('user')
		current_user = self.get_argument(name='id',default='None')
		# print('current_user:',current_user)
		if current_user:
			return current_user
		return None


class MessageHandler(BaseWebSocketHandler):

	@property
	def download(self):
		return self.application.download

	def open(self):   #当一个新的WebSocket连接建立后被调用。
		# logger.info('ok')
		self.__dict__['name'] = self.current_user
		ProStatus().user_connect(self)
		ProStatus().trigger('[%s]-[%s]：上线'%(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
				self.__dict__['name']))
		ProStatus().trigger('ip:%s'%self.request.remote_ip)
		data = self.download.getStatus()
		ProStatus().triggerUpdateData(data)


	def on_message(self, message): #当客户端发送消息message过来时被调用，注意此方法必须被重写。
		# print(self.request.remote_ip)
		ProStatus().trigger('[%s]-[%s]-说：%s'%(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
				self.__dict__['name'],message))

	def on_close(self): #当WebSocket连接关闭后被调用。
		ProStatus().user_remove(self)
		ProStatus().trigger("[%s]-[%s] 离线" % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),self.__dict__['name']))



def updatedata(download=None):
	if download:
		data = download.getStatus(status=1)	#返回未下载完成数据
		# print(data)
		ProStatus().triggerUpdateData(data)